package packageDataAccess;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import packageException.*;
import packageModel.Promotion;

/**
 *
 * @author Lionel & Julien
 */
public class PromotionSyllathequeData {
    
    /**
     * Nombre de promotion correspondant au syllabus passé en paramètre
     * 
     * @param syllabusId
     * @return nbPromo
     * @throws PromotionException
     * @throws ReductionException
     * @throws DataException  
     */
    public int getNbPromotionById (int syllabusId) throws 
            PromotionException, 
            ReductionException,
            DataException{
        int promo = 0;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            ReductionSyllathequeData psdb = new ReductionSyllathequeData();
            int resultatRequete = psdb.getNbReduction(syllabusId);

            // SQL
            String requeteSql = "SELECT * "
                    + "FROM Promotion "
                    + "WHERE promoId = ? "
                    + "ORDER BY dateFin "
                    + "DESC";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setInt(1, resultatRequete);
            prepStat.setMaxRows(1);

            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            promo = donnees.getRow();

            // Connexion à la base de données
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new PromotionException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return promo;
    }
    
    
    
    
    /**
     * Retourne la meilleure promotion !
     * Nous avons pris la décision de choisir la réduction avec la date de fin la plus éloignée comme réduction principale !
     * Cela engendre qu'un syllabus aura au maximum une réduction
     * 
     * @param syllabusId
     * @return Promotion
     * @throws PromotionException
     * @throws ReductionException
     * @throws DataException  
     */
    public Promotion getPromotionById (int syllabusId) throws 
            PromotionException, 
            ReductionException, 
            DataException{
        Promotion promo = null;
        ArrayList<Promotion> tabPromo = new ArrayList<Promotion>();
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            ReductionSyllathequeData psdb = new ReductionSyllathequeData();
            ArrayList<Integer> resultatRequete = psdb.getBestReduction(syllabusId);
            
            // Traitement des dates
            java.util.Date today = new java.util.Date();
            GregorianCalendar auj = new GregorianCalendar();
            auj.setTime(today);
            java.sql.Date truc = new java.sql.Date(auj.getTimeInMillis());
            
            // On boucle sur les réductions
            for(int i = 0; i < resultatRequete.size(); i++) {
                // SQL
                String requeteSql = "SELECT * "
                        + "FROM Promotion "
                        + "WHERE promoId = ? "
                        + "AND ? BETWEEN dateDebut AND dateFin "
                        + "ORDER BY dateFin "
                        + "DESC";

                // Traitement
                PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
                prepStat.setInt(1, resultatRequete.get(i));
                prepStat.setDate(2, truc);
                prepStat.setMaxRows(1);

                ResultSet donnees = prepStat.executeQuery();
                while(donnees.next()) {
                    // Date
                    java.sql.Date dateDebut = donnees.getDate(3);
                    GregorianCalendar gd = new GregorianCalendar();
                    gd.setTime(dateDebut);

                    java.sql.Date dateFin = donnees.getDate(4);
                    GregorianCalendar gf = new GregorianCalendar();
                    gf.setTime(dateFin);

                    // Création d'un objet Promotion afin de pouvoir les comparer plus tard
                    promo = new Promotion(
                                donnees.getInt(1), 
                                donnees.getDouble(2), 
                                gd, 
                                gf
                            );
                    // On l'ajoute à notre ArrayList
                    tabPromo.add(promo);
                }
            }
           
            // DATE
            java.util.Date todayPromo = new java.util.Date();
            GregorianCalendar aujPromo = new GregorianCalendar();
            aujPromo.setTime(todayPromo);
            int bestPromo = -1;
                
            // Calcul afin de connaître la promotion actuelle qui a la date de fin la plus éloignée.
            // Ce sera toujours celle-là qui sera utilisée. En effet, si deux promotions sont superposées, 
            // c'est qu'il y en a une qui est devenue obsolète, nous avons décidé que c'était celle avec la date de fin la plus proche d'aujourd'hui
            for(int i = 0; i < tabPromo.size(); i++) {                
                if(aujPromo.before(tabPromo.get(i).getDateFin())) {
                    bestPromo = i;
                    aujPromo = tabPromo.get(i).getDateFin();
                }
            }
                
            // Des entrées ont bien été trouvées, cependant, celles-ci sont dépassées
            // Si c'est le cas, on retourne une promotion nulle !
            if(bestPromo == -1) {
                connexion.close();
                return null;
            }
            
            // Création de la promotion concernant notre syllabus !
            promo = new Promotion(
                        tabPromo.get(bestPromo).getCodeId(),
                        tabPromo.get(bestPromo).getReduction() * 100, 
                        tabPromo.get(bestPromo).getDateDebut(), 
                        tabPromo.get(bestPromo).getDateFin()
                    );
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new PromotionException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return promo;
    }
    
}
